package com.es.www.kyl.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.es.www.kyl.bean.req.client.DoExerciseBaseReq;
import com.es.www.kyl.bean.res.client.QuestionDetailVO;
import com.es.www.kyl.bean.res.client.QuestionInfoVO;
import com.es.www.kyl.constant.BaseConstants;
import com.es.www.kyl.constant.RedisConstants;
import com.es.www.kyl.domain.Question;
import com.es.www.kyl.domain.UserPracticeRoundDo;
import com.es.www.kyl.domain.UserPracticeState;
import com.es.www.kyl.mapper.QuestionMapper;
import com.es.www.kyl.mapper.UserAnswerLogMapper;
import com.es.www.kyl.mapper.UserPracticeStateMapper;
import com.es.www.kyl.service.help.ExerciseHelper;
import com.es.www.kyl.util.RedisUtils;
import com.es.www.kyl.util.UserContextHolder;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author Estranger
 * @date 2025/8/25
 * description
 */
public abstract class AbstractRoundManager {

	@Autowired
	protected UserPracticeStateMapper userPracticeStateMapper;
	@Autowired
	protected QuestionMapper questionMapper;
	@Autowired
	protected RedisUtils redisUtils;
	@Autowired
	protected ExerciseHelper exerciseHelper;
	@Autowired
	protected UserAnswerLogMapper userAnswerLogMapper;

	/**
	 * 获取初始题目列表
	 *
	 * @param categoryId
	 * @param roundId
	 * @return
	 */
	abstract List<Integer> getinitialQuestionIdList(Integer categoryId, String commonRoundId, String roundId);

	/**
	 * 继续轮次获取题目列表
	 *
	 * @param req
	 * @param practiceType
	 * @return
	 */
	public abstract QuestionInfoVO continueRound(DoExerciseBaseReq req, BaseConstants.UserPracticeType practiceType);


	/**
	 * 创建新一个轮次
	 *
	 * @param req
	 * @return
	 */
	public QuestionInfoVO initRound(DoExerciseBaseReq req, BaseConstants.UserPracticeType practiceType) {
		//清除旧的轮次
		clearOldRound(req.getCategoryId(), practiceType);
		//创建新轮次
		String roundId = UUID.randomUUID().toString();
		return createNewRound(req.getCategoryId(), req.getCommonRoundId(), roundId, practiceType);
	}


	protected void clearOldRound(Integer categoryId, BaseConstants.UserPracticeType practiceType) {
		//查询是否有旧的轮次
		Integer userId = UserContextHolder.getUserId();
		List<UserPracticeState> userPracticeStateList = userPracticeStateMapper.selectList(new LambdaQueryWrapper<UserPracticeState>()
				.eq(UserPracticeState::getCategoryId, categoryId)
				.eq(UserPracticeState::getUserId, userId)
				.eq(Objects.nonNull(practiceType), UserPracticeState::getPracticeType, practiceType.getType())
		);
		if (CollectionUtils.isNotEmpty(userPracticeStateList)) {
			userPracticeStateList.forEach(userPracticeState -> {
				//删除用户做题状态
				userPracticeStateMapper.deleteById(userPracticeState.getId());
				//删除旧的轮次
				redisUtils.deleteCache(getRoundKey(userPracticeState.getRoundId()));
			});
		}
	}

	private QuestionInfoVO createNewRound(Integer categoryId, String commonRoundId, String roundId, BaseConstants.UserPracticeType practiceType) {
		List<Integer> questionIdList = getinitialQuestionIdList(categoryId, commonRoundId, roundId);
		UserPracticeState userPracticeState = new UserPracticeState();
		userPracticeState.setRoundId(roundId);
		userPracticeState.setCategoryId(categoryId);
		userPracticeState.setRoundQuestionCount(questionIdList.size());
		if (Objects.nonNull(practiceType)) {
			userPracticeState.setPracticeType(practiceType.getType());
		}
		userPracticeState.setUserId(UserContextHolder.getUserId());
		userPracticeState.setCreateBy(UserContextHolder.getUserId());
		userPracticeState.setCreateTime(new Date());

		//初始化用户练习状态
		userPracticeStateMapper.insertSelective(userPracticeState);
		return QuestionInfoVO.builder()
				.questionDetailInfo(exerciseHelper.getQuestionDetail(questionIdList.get(0)))
				.questionIds(questionIdList)
				.roundId(roundId)
				.build();
	}

	protected String getRoundKey(String roundId) {
		String key = RedisConstants.USER_PRACTICE_ROUND_QUESTION_KEY_PREFIX + UserContextHolder.getUserId() + ":";
		if (StringUtils.isNotEmpty(roundId)) {
			return key + roundId;
		}
		return key;
	}
}
